不定長度參數 Variadic Functions
Golang 中,有些函式的參數長度是不固定的,像是 fmt 套件的 Printf 及 Sprintf 函式,這兩個函式,第一個參數是做為模板
的字串,第二個以後的參數就是我們要填入的值,而值的數量是不固定的
。
這是由於 Go 支援 不定長度參數這個強大的東東
package main
import (
"log"
)
func sum(args ...int) int {
sum := 0.0
for _, e := range args {
sum += e
}
return sum
}
func main() {
s := sum(1, 2, 3, 4, 5)
fmt.Println(s)
}
輸出為 15
s1 := sum(1, 2)
s2 := sum(1, 2, 5)
s3 := sum(9, 4, 8, 7)
s4 := sum(1, 0, 4, 8, 5, 7, 6)
不定參數傳入函式後,對參數本身來說是一個 slice[],在函式中透過此 slice[] 即可取得個別的參數值。
至於 slice[] 是什麼呢??
簡單來說就是 array ,之後再來詳談
傳值呼叫 vs. 傳址呼叫
如同 C 語言,所有 Go 的函式都是傳值呼叫 (call by value),而這個值有可能是基本型別或指標或其他型別。當我們傳遞指標時,我們會拷貝指標的位址,但不會拷貝指標所指向的值;當值很大時,傳遞指標比傳整個值有效率。
而在實際應用的過程當中
有些變數、方法的操作必須經由 address 才有辦法更改
如 database 的 scan , 或是 json.UnMarshal 的寫入
會看到很多 * & 符號
init
init() 是一個特殊的函式,若程式碼內有 init 會在程式一開始執行的時候呼叫該函式,順序在 main 函式之前。
init()
autoload()
start()
...etc
go 的 func 宣告中常常會看到一堆括號,一堆奇奇怪怪的括號
讓我們來稍微檢視一下
不帶 return
func functionName(name string) {}
func functionName(name1 string, name2 string) {}
匿名函式
func(){
//do something
}
匿名函式 + 執行
func(){
//do something
}()
一個 return 值
func functionName(name string) string {}
func functionName(name string) (str string) {}
兩個 return 值
func functionName(x, y int) (int, int) {}
兩個 return 值 + 預先宣告
func functionName(x, y int) (return1 int , return2 int) {}
帶 receiver 的函式
func (v Revicers) receiverFunc() float64 {}
func (v *Revicers) receiverFunc(f float64) {}
一開始看到這些 func 時總是令我覺得非常困惑,但多看幾次會有一點點方向,實際用過後才會了解到底功能在哪
指標接受器 Pointer Receivers
『宣告』的動作定義了程式的各種實體物件以及部分或全部的屬性 Go 主要有四種類型的宣告語句:
var 變數
const 常數
type 型別
func 函式實體
帶 recevier 的 func 宣告方式如下
recevier 寫在 func 和 method name 之間
type Revicers struct {
X, Y float64
}
func (v Revicers) SubFunc() float64 {
return math.Max(v.X, v.Y)
}
func main() {
a1 := Revicers{28, 25}
fmt.Println(a1.SubFunc())
}
輸出為 28
(v Revicers) 就是 recevier
這個命名 func (v Revicers) SubFunc() float64 {} 可以解讀為
SubFunc() method 擁有一個「類別為 Revicers 宣告為 v 」的 receiver